package cn.founder.basic.service.impl;

import cn.founder.basic.constant.BaseConstant;
import cn.founder.basic.exception.BusinessException;
import cn.founder.basic.service.IVerifyCodeService;
import cn.founder.basic.util.StrUtils;
import cn.founder.user.domain.User;
import cn.founder.user.mapper.UserMapper;
import com.fasterxml.jackson.databind.ser.Serializers;
import io.netty.util.internal.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {

    //注入usermapper查询用户是否注册过
    @Autowired
    private UserMapper userMapper;

    //注入进行redis数据库操作
    @Autowired
    private RedisTemplate redisTemplate;


    @Override
    @Transactional //加上控制
    public void smsCode(Map<String,String> param) {
        //接收前台从接口发来的类型
        String phone = param.get("phone");
        String type =  param.get("type");
//        1.校验
//        1.1 手机号不能为空
        if(StringUtils.isEmpty(phone) ||StringUtils.isEmpty(type)){
            //---前端传递进来的手机号字段如果是空的 直接报错
            throw new BusinessException("参数不能为空！");
        }
        String businessKey = "";
        //假如获取验证码类型是注册
        if(type.equals("register")){
            //        1.2 手机号不能被注册 查询user表
            //---使用UserMapper对象查询如果有结果就是已经被注册
            User userByPhone = userMapper.loadByPhone(phone);
            if(userByPhone != null){
                throw new BusinessException("用户已注册，请直接登录，或找回密码！");
            }

            businessKey = BaseConstant.BUSINESS_TYPE_REGISTER + phone;
        }else if(type.equals("binder")){//微信绑定逻辑
            businessKey = BaseConstant.BUSINESS_TYPE_BINDER + phone;
        }
        //发送验证码
        sendCode(businessKey);



    }

    //将发送验证码代码公共抽出
    public void sendCode(String businessKey){
        //        1.3 验证码是否有效  拼接key从redis查询出验证码  key  -->  business_type_register:15982495855
        //---这里从redis数据库获取前缀+手机号的key 是否存在   拿到我的value对象
        Object keyempty = redisTemplate.opsForValue()
                .get(businessKey);
//        2.判断验证码是否有效  value有值                   value --> 9527:4612168213273121324
        String code = "";//这里将我要重新赋值的验证码  赋值对象字符串  拿出来  写到一半发觉不能连续用
//        2.1.查询到了value，有效，还需要判断是否过了重发时间
        if(keyempty != null) {
            //---这里用引号做分割  0元素是我的验证码   1元素是我的时间戳
            String keyTime = keyempty.toString().split(":")[1];
//        2.1.1 如果没有过重发时间，报错：请勿重复获取验证码  当前时间 - 4612168213273121324 < 1*60*1000
            //---现在的时间减去 时间戳时间小于一分钟
            if (System.currentTimeMillis() - Long.valueOf(keyTime) <= 1 * 60 * 1000){
                throw new BusinessException("请过了1分钟后在尝试获取验证码哦！");
            }
//        2.1.2 如果过了，使用原来的验证码   code = 9527   拿到value里面的0号元素  验证码
            code = keyempty.toString().split(":")[0];
        }else {
//        2.2 没有查询到，验证码失效（或者是第一次发）
            //获取新的验证码发送  放到下面的业务部分一起做
//        2.2.1 直接生成新的验证码   code = 9527
            code = StrUtils.getComplexRandomString(4);
        }
//        3.处理业务
//        3.1 将code保存到redis并设置3分钟过期
//        key  --> business_type_register:15982495855
//        value --> 9527:4612168213273121324
        redisTemplate.opsForValue().set(
                //key 是我的 头字段+手机号
                businessKey,
                //value是 验证码+时间戳
                code + ":" + System.currentTimeMillis(),
                //设定 3分钟后过期
                3,
                //这是 单位  分钟
                TimeUnit.MINUTES);
//        3.2 发送验证码
        //SmsUuils.send()  这里没有短信接口资源  用打印字符串代替
        System.out.println("您的验证码是："+code+" 请在3分钟内使用！");
    }
}
